﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using BoYuanCore.CodeGenerator.code;

namespace BoYuanCore.CodeGenerator.FineuiCore
{
    public partial class FineUIToMvc : FineUIPage
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void btn_showCode_OnClick(object sender, EventArgs e)
        {
            string xml = FillterInvalidCode(txa_old.Text)
                    .Replace(">", ">" + Environment.NewLine)
                    .Replace("<", Environment.NewLine + "<")
                ;

            string[] data = xml.Split(Environment.NewLine.ToCharArray());
            string row = string.Empty;
            StringBuilder sbTemp = new StringBuilder();

            List<MLModel> mlList = new List<MLModel>();
            MLModel mo;
            MLModel moPrev; //上一条
            string tagName;
            int rowid = 0;

            //整理格式(每一行:<> </ > < /> 或 文本)
            try
            {
                for (int i = 0; i < data.Length; i++)
                {
                    #region 整row代码

                    row = data[i].Trim();
                    if (string.IsNullOrEmpty(row) || row.Contains("PageManager")) continue;

                    //
                    if (row.Substring(0, 1) != "<")
                    {
                        sbTemp.AppendLine(row); //纯文本
                    }
                    else
                    {
                        //判断是否有闭合标签
                        if (!HasEndTag(row))
                        {
                            //找下一行数据，找闭合标签
                            for (int j = i + 1; j < data.Length; j++)
                            {
                                row += " " + data[j].Trim();
                                if (HasEndTag(data[j].Trim()))
                                {
                                    i = j;
                                    sbTemp.AppendLine(row); //有闭合标签
                                    break;
                                }
                            }
                        }
                        else
                        {
                            sbTemp.AppendLine(row); //有闭合标签
                        }
                    }

                    #endregion

                    #region 装载ml列表数据

                    mo = new MLModel();
                    mo.RowId = rowid++;

                    tagName = GetTag(row, mo.RowId, out var tagType);

                    mo.Text = row;
                    mo.Tag = tagName;
                    mo.TagType = tagType;

                    if (mlList.Count == 0)
                    {
                        mo.ParentId = -1; //根级
                    }
                    else
                    {
                        if (tagType == -10) //</  >
                        {
                            //查询上一个匹配的节点类型,设置关联匹配
                            moPrev = mlList.Where(p => p.Tag == mo.Tag && p.TagType == -1)
                                .OrderByDescending(p => p.RowId).FirstOrDefault();
                            moPrev.TagType = mo.RowId;
                            mo.TagType = moPrev.RowId;
                        }
                    }

                    mlList.Add(mo);

                    #endregion

                }

                //xml = sbTemp.ToString();
                //txa_new.Text = xml;
            }
            catch (Exception exception)
            {
                AlertError("整理格式错误!" + exception.Message);
                return;
            }

            Grid1.DataSource = mlList;
            Grid1.DataBind();

            //生成fineui Mvc view
            try
            {
                sbTemp = new StringBuilder();
                for (int i = 0; i < mlList.Count; i++)
                {
                    mo = mlList[i];
                    if (mo.IsTraversal) continue;
                    sbTemp.Append(GetCode(mo, mlList, 1));
                }
            }
            catch (Exception exception)
            {
                AlertError("生成Mvc viewi错误!" + exception.Message);
                return;
            }

            //todo 待实现Grid 的Column
            string newMvcCode =
                    sbTemp.ToString().Substring(1)
                    .Replace("(,F.", "(" + Environment.NewLine + "F.")
                    .Replace("),F.", ")" + Environment.NewLine + ",F.")

                ;
            txa_new.Text = newMvcCode;
        }

        private List<string> tagList = new List<string> { "items", "toolbars", "tools", "rows", "menu", "tabs", "nodes", "columns" };

        private string GetCode(MLModel mo, List<MLModel> list, int level)
        {
            if (mo.IsTraversal) return string.Empty;

            if (mo.TagType == mo.RowId)//< />
            {
                list.FirstOrDefault(p => p.RowId == mo.RowId).IsTraversal = true;
                return GetAttribute(mo.Text) + Environment.NewLine;
            }
            else if (mo.Tag.Length > 0)//<  > 或 </  >。获取开始和结束标签
            {
                MLModel moNext = list.FirstOrDefault(p => p.RowId == mo.TagType);
                list.FirstOrDefault(p => p.RowId == mo.RowId).IsTraversal = true;
                list.FirstOrDefault(p => p.RowId == moNext.RowId).IsTraversal = true;
                StringBuilder sb = new StringBuilder();
                sb.Append(GetAttribute(mo.Text));
                level++;
                for (int i = mo.RowId + 1; i < moNext.RowId; i++)
                {
                    var moTemp = list.FirstOrDefault(p => p.RowId == i);
                    sb.Append(GetCode(moTemp, list, level));
                }
                if (tagList.Contains(mo.Tag.ToLower()))
                {
                    sb.Append(")");
                }

                return sb.ToString();
            }
            else //文本
            {
                list.FirstOrDefault(p => p.RowId == mo.RowId).IsTraversal = true;
                return mo.Text + Environment.NewLine;
            }
        }

        private string GetTag(string row, int rowid, out int tagType)
        {
            string tempStr;
            if (row.Length == 0)
            {
                tagType = -2;//文本
                return string.Empty;
            }
            if (row.IndexOf("</") == 0) //</ >
            {
                tagType = -10;//需要查询上一个节点
                return StringHelper.GetBetweenStr(row, "</", ">");

            }
            else if (row.Substring(0, 1) == "<")
            {

                if (row.Substring(row.Length - 2, 2) == "/>") //< />
                {
                    tagType = rowid;
                    tempStr = StringHelper.GetBetweenStr(row, "<", " ");
                    if (tempStr.Length > 0)//<row id='123' />
                    {
                        return tempStr;
                    }
                    else//<row/>
                    {
                        return row.Replace("/>", string.Empty).Replace("<", string.Empty);
                    }

                }
                else //< >
                {
                    tagType = -1;
                    tempStr = StringHelper.GetBetweenStr(row, "<", " ");
                    if (tempStr.Length > 0)//<row id='123' >
                    {
                        return tempStr;
                    }
                    else//<row>
                    {
                        return row.Replace(">", string.Empty).Replace("<", string.Empty);
                    }
                }
            }
            else //文本
            {
                tagType = -2;
                return string.Empty;
            }
        }

        /// <summary>
        /// 默认外层容器
        /// </summary>
        private string defaultPanelId { get; set; }

        /// <summary>
        /// 解析特性
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        private string GetAttribute(string row)
        {
            row = row.Replace("/>", string.Empty).Replace("<", string.Empty).Replace(">", string.Empty);
            StringBuilder sb = new StringBuilder();

            string[] attrs = row.Split(' ');
            string tagName = attrs[0];

            if (row.Contains(" ")) // FormRow runat="server" BodyPadding="15px 15px" 
            {
                sb.Append(",F." + tagName + "()");

                int num;//双引号个数
                string attrOne = string.Empty;
                string attrInfo = string.Empty;
                for (int i = 1; i < attrs.Length; i++)
                {
                    if (attrs[i].Length == 0) continue;

                    num = Regex.Matches(attrs[i], "\"").Count;
                    if ((num & 1) == 1)//奇数
                    {
                        attrOne += attrs[i];
                        //找下一个特性，找闭合标签
                        for (int j = i + 1; j < attrs.Length; j++)
                        {
                            attrOne += " " + attrs[j];
                            if (((Regex.Matches(attrOne, "\"").Count) & 1) == 0)//偶数
                            {
                                i = j;
                                break;
                            }
                        }

                        attrInfo = attrOne;
                    }
                    else
                    {
                        attrOne = string.Empty;
                        attrInfo = attrs[i];
                    }

                    //attrOne: BodyPadding="15px 15px" 
                    sb.Append(GetAttrCode(attrInfo, tagName));//
                }
            }
            else // Row Items PageItems 等
            {
                sb.Append("." + tagName + "(");
            }

            return sb.ToString();
        }

        /// <summary>
        /// 获取对应的特性的代码
        /// </summary>
        /// <param name="info"></param>
        /// <param name="tagName">标签名称</param>
        /// <returns></returns>
        private string GetAttrCode(string info, string tagName)
        {
            //attrOne: BodyPadding="15px 15px" 
            string key = info.Split('=')[0];
            string value = info.Split('=')[1];

            switch (key)
            {
                case "OnClick":
                    return ".OnClick(Url.Action(" + value + ")," + defaultPanelId + ")";
                case "ID":
                    if (string.IsNullOrEmpty(defaultPanelId))
                    {
                        defaultPanelId = value; //"Panel1"
                    }
                    return ".ID(" + value + ")";
                case "Text":
                    return ".Text(" + value + ")";
                case "Label":
                    return ".Label(" + value + ")";
                case "Icon":
                    return ".Icon(Icon." + value.Replace("\"", string.Empty) + ")";
                case "ButtonIcon":
                    return ".ButtonIcon(Icon." + value.Replace("\"", string.Empty) + ")";
                case "Target":
                    return ".Target(Target." + value.Replace("\"", string.Empty) + ")";
                case "Layout":
                    return ".Layout(LayoutType." + value.Replace("\"", string.Empty) + ")"; ;
                case "DisplayType":
                    return ".DisplayType(CheckBoxDisplayType." + value.Replace("\"", string.Empty) + ")";
                case "DataKeyNames":
                    return ".DataIDField(" + value + ")";
                case "TextMode":
                    return ".TextMode(TextMode." + value.Replace("\"", string.Empty) + ")";
                case "ClientIDMode":
                    return string.Empty;
            }

            if (key.Contains("Position"))
            {
                return GetPositionCode(value, tagName);
            }

            if (key.IndexOf("Change") > 0) //OnPageIndexChange OnSelectedIndexChanged 等事件
            {
                if (key == "OnPageIndexChange") key = "OnPageIndexChanged";
                return "." + key + "(Url.Action(\"" + value + "\")," + defaultPanelId + ")";
            }

            string valueTemp = value.Replace("\"", string.Empty);
            switch (valueTemp.ToLower())
            {
                case "true":
                    return "." + key + "(true)";
                case "false":
                    return "." + key + "(false)";
            }

            string tempIntStr = valueTemp.Replace("px", string.Empty);
            if (int.TryParse(tempIntStr, out var tempInt))
            {
                return "." + key + "(" + tempIntStr + ")";
            }

            return "." + key + "(" + value + ")";
        }


        /// <summary>
        /// 判断是否为末尾标签
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        private static bool HasEndTag(string info)
        {
            info = info.Trim();

            if (info.Length == 0)
            {
                return false;
            }

            return info.Substring(info.Length - 1, 1) == ">";
        }

        /// <summary>
        /// 替换无意义标签
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        private string FillterInvalidCode(string info)
        {
            info = info.ReplaceStringIgnoreCase("world", "csharp")
                .ReplaceStringIgnoreCase("runat=\"server\"", string.Empty)
                .ReplaceStringIgnoreCase("AutoPostBack=\"True\"", string.Empty)
                .ReplaceStringIgnoreCase("AutoPostBack=\"False\"", string.Empty)
                .ReplaceStringIgnoreCase("EnablePostBack=\"True\"", string.Empty)
                .ReplaceStringIgnoreCase("EnablePostBack=\"False\"", string.Empty)
                .ReplaceStringIgnoreCase("EnableAjax=\"True\"", string.Empty)
                .ReplaceStringIgnoreCase("EnableAjax=\"False\"", string.Empty)
                .ReplaceStringIgnoreCase("<f:", "<")
                .ReplaceStringIgnoreCase("</f:", "</");

            //过滤注释代码
            FillterComment(info, out var code);
            string tempStr = code;

            //Grid 列过滤
            FillterGridColumnList(tempStr, out code);

            return code.Replace("ColumnsReplace", "Columns");
        }

        private void FillterGridColumnList(string str, out string code)
        {
            if (str.IndexOf("<Columns>") > 0)
            {
                string colStr = StringHelper.GetBetweenStr(str, "<Columns>", "</Columns>");
                //ColumnList.Add(colStr);
                //ColumnsCount += 1;
                FillterGridColumnList(str.Replace("<Columns>" + colStr + "</Columns>", "<ColumnsReplace></ColumnsReplace>"), out code);
            }
            else
            {
                code = str;
            }
        }

        /// <summary>
        /// 递归过滤注释代码
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private void FillterComment(string str, out string code)
        {
            if (str.IndexOf("<%--") > 0)
            {
                string delStr = StringHelper.GetBetweenStr(str, "<%--", "--%>");
                FillterComment(str.Replace("<%--" + delStr + "--%>", string.Empty), out code);
            }
            else
            {
                code = str;
            }
        }

        private string GetPositionCode(string value, string tagName)
        {
            value = value.Replace("\"", string.Empty);
            switch (tagName.ToLower())
            {
                case "region":
                    return ".RegionPosition(Position." + value + ")";
                case "toolbar":
                    return ".Position(ToolbarPosition." + value + ")";
            }

            //
            return ".Position(Position." + value + ")";
        }

    }

    /// <summary>
    /// ml实体
    /// </summary>
    public class MLModel
    {
        /// <summary>
        /// 行号
        /// </summary>
        public int RowId { get; set; }

        /// <summary>
        /// 行文本
        /// </summary>
        public string Text { get; set; }

        /// <summary>
        /// 行标签
        /// </summary>
        public string Tag { get; set; }

        /// <summary>
        /// 行标签类型(配对rowid)
        /// TagType==RowId : <  />
        /// TagType==-1 : <  >
        /// TagType >-1 : </  >
        /// TagType==-2 : 非标签(文本类型)
        /// </summary>
        public int TagType { get; set; } = -1;

        /// <summary>
        /// 层级
        /// </summary>
        public int Level { get; set; }

        /// <summary>
        /// 上级id
        /// </summary>
        public int ParentId { get; set; } = -1;

        /// <summary>
        /// 是否遍历
        /// </summary>
        public bool IsTraversal { get; set; } = false;

    }
}